package org.khd.base.service.impl;

import org.khd.auth.domain.Permission;
import org.khd.auth.mapper.PermissionMapper;
import org.khd.base.annotation.BasePermission;
import org.khd.base.service.IAutoScanPermissionService;
import org.khd.base.utils.ClassUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@Service
public class AutoScanPermissionServiceImpl implements IAutoScanPermissionService {

    @Value("${scan.paths}")
    private String paths;
    @Value("${scan.tages}")
    private Boolean tages;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public void scan() {
        //是否开启扫描权限配置
        if (!tages) return;

        //1.获取项目里面需要扫描controller --期望得到List<Class>
        //paths 需要扫描的包路径
        List<Class> allClassName = ClassUtils.getAllClassName(paths);

        //扫描后存放的父级资源
        List<Permission> permissions = new ArrayList<>();

        //2.循环allClassName，得到每一个controller
        for (Class aClass : allClassName) {
            //获取controller上的注解
            BasePermission annotation = (BasePermission) aClass.getAnnotation(BasePermission.class);

            //annotation为null时
            if (annotation == null) continue;
            Permission parent = new Permission();
            //数据组装
            parent.setName(annotation.name());
            parent.setDescs(annotation.desc());
            RequestMapping requestMapping = (RequestMapping) aClass.getAnnotation(RequestMapping.class);
            parent.setUrl(requestMapping.value()[0]);
            parent.setSn(aClass.getSimpleName());
            permissions.add(parent);
            //检查父级菜单数据库是否已经维护 没有添加 否则就修改
            Permission parentInDb = permissionMapper.queryBySn(parent.getSn());
            if (parentInDb != null){
                parent.setId(parentInDb.getId());
                permissionMapper.update(parent);
            }else {
                permissionMapper.add(parent);
            }

            //解决子级资源菜单
            //1.获取controller里的方法
            Method[] methods = aClass.getMethods();
            for (Method method : methods) {
                //获取方法上添加BasePermission注解的方法
                BasePermission methodAnnotation = method.getAnnotation(BasePermission.class);
                if (methodAnnotation == null) continue;
                //添加BasePermission注解的方法，生成权限资源数据
                Permission child = new Permission();
                child.setName(methodAnnotation.name());
                child.setDescs(methodAnnotation.desc());
                //类名：方法名
                child.setSn(parent.getSn() + ":" + method.getName());
                child.setParentId(parent.getId());
                //方法上添加的注解的路径有多种情况
                String childUrl = getChildUrl(method);
                child.setUrl(parent.getUrl() + childUrl);

                //检查子级菜单数据库是否已经维护 没有添加 否则就修改
                Permission childInDb = permissionMapper.queryBySn(child.getSn());
                if (childInDb != null){
                    child.setId(childInDb.getId());
                    permissionMapper.update(child);
                }else {
                    child.setParentId(parent.getId());
                    permissionMapper.add(child);
                }
            }
        }
    }

    private String getChildUrl(Method method){
        //2.获取controller里的方法上的权限

        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping != null){
            return requestMapping.value().length > 0 ? requestMapping.value()[0] : "";
        }

        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        if (getMapping != null){
            return getMapping.value().length > 0 ? getMapping.value()[0] : "";
        }

        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        if (putMapping != null){
            return putMapping.value().length > 0 ? putMapping.value()[0] : "";
        }

        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        if (deleteMapping != null){
            return deleteMapping.value().length > 0 ? deleteMapping.value()[0] : "";
        }

        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        if (postMapping != null){
            return postMapping.value().length > 0 ? postMapping.value()[0] : "";
        }

        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping != null){
            return patchMapping.value().length > 0 ? patchMapping.value()[0] : "";
        }

        return "";
    }
}
